<?php
/**
 * Created by PhpStorm.
 * User: lee
 * Date: 2018/1/9
 * Time: 下午3:39
 */

namespace Biz\model;

use Biz\cache\Sku as cSku;
use Biz\model\GoodsBasicInfo as mGoodsBasicInfo;
use Biz\model\GoodsExtendInfo as mGoodsExtendInfo;
use Biz\model\GoodsSkuAttr as mGoodsSkuAttr;
use Biz\validate\GoodsSku as vGoodsSku;
use Medoo\Medoo;


final class GoodsSku extends \Doraemon\pockets\datebase\BaseDbModel
{
    const _CONFIG_FILE_ = 'db_shop';

    const _CONFIG_SELECT_ = 'db_shop';

    const _DATABASE_ = 'shop';

    const _TABLE_NAME = 'goods_sku';


    //sku状态
    const STATUS_PASSED = 1;//已审核
    const STATUS_DELETE = 9;//删除


    //允许通过createOrEdit操作的字段列表，进行输入转换

    protected static $fields = [
        'id',
        'title' => ['trim', 'htmlspecialchars'],
        'sku_attr_t1',
        'sku_attr_t2',
        'price',
        'stock',
        'weight',
        'volume',
        'forecast_ship_time',
        'sku_no' => ['trim'],
        'extinfo',
        'status',
    ];


    public static function saveSkuInfo($shopId, $goodsId, $skuInfos)
    {
        foreach ($skuInfos as $skuInfo) {
            if (!vGoodsSku::validate($skuInfo, 'saveSku')) {

                $msg = vGoodsSku::firstError();

                throw new \Exception($msg);
            }
            self::update(['stock' => $skuInfo['stock'], 'price' => $skuInfo['price']],
                ['goods_id' => $goodsId, 'shop_id' => $shopId, 'id' => $skuInfo['id']]);
        }
    }

    //保存商品SKU信息
    public static function createOrEdit($uid, $goodsId, $data, $scenes = null)
    {
        try {

            $info = self::select_master("*",
                Medoo::raw(' where goods_id=:goods_id and sku_attr_t1=:sku_attr_t1 and sku_attr_t2=:sku_attr_t2 for update',
                    [
                        ':goods_id' => $goodsId,
                        ':sku_attr_t1' => $data['sku_attr_t1'],
                        ':sku_attr_t2' => $data['sku_attr_t2']
                    ]));

            $info = array_shift($info);


            $method = !empty($info) ? 'update' : 'insert';

            if (!is_null($scenes)) {

                //提交字段进行校验
                if (!vGoodsSku::validate($data, $scenes)) {

                    $msg = vGoodsSku::firstError();

                    throw new \Exception($msg);
                }
            }

            $data = self::buidData($data);

            switch ($method) {
                case 'insert':
                    $data['shop_id'] = $uid;
                    $data['goods_id'] = $goodsId;
                    $data['addtime'] = date('Y-m-d H:i:s');
                    $data['extinfo'] = !is_null($data['extinfo']) ? $data['extinfo'] : '';

                    $ret = self::insert($data);

                    $skuId = self::id();

                    break;
                case 'update':

                    $ret = self::update($data, ['id' => $info['id']]);
                    cSku::mDelItems($goodsId);
                    $skuId = $info['id'];

                    break;
            }


            if ($ret->errorCode() !== '00000') {
                throw new \Exception('操作失败,请重试');
            }

            //function addLog($foreign_id, $p_order_no, $goods_id, $type, $promo_id, $sku_id, $change_data, $action_uid,$target_data)

            if (isset($data['stock'])) {
                GoodsStockLog::addLog(
                    $uid,
                    $uid,
                    $data['goods_id'],
                    GoodsStockLog::TYPE_ADMIN_ACTION,
                    0,
                    0,
                    $skuId,
                    $data['stock'],
                    $uid,
                    $data['stock']
                );
            }
            return $skuId;

        } catch (\Exception $e) {


            throw $e;
        }
    }

    public static function getSkuList($goodsIds, $isAll = true)
    {
        $data = [];
        $where = ['goods_id' => $goodsIds];

        if (!$isAll) {
            $where['status'] = self::STATUS_PASSED;
        }

        $skus = self::select_master("*", $where);


        if (empty($skus)) {
            return null;
        }

        $skuAttrs = mGoodsSkuAttr::getList($goodsIds);

        foreach ($skus as $key => $sku) {

            if ($sku['sku_attr_t1'] > 0 && isset($skuAttrs[$sku['sku_attr_t1']])) {
                $skus[$key]['attr']['t1'] = $skuAttrs[$sku['sku_attr_t1']];
            }

            if ($sku['sku_attr_t2'] > 0 && isset($skuAttrs[$sku['sku_attr_t2']])) {
                $skus[$key]['attr']['t2'] = $skuAttrs[$sku['sku_attr_t2']];
            }

            $skus[$key]['price'] = $sku['price'];
        }

        foreach ($skus as $key => $sku) {
            $data[$sku['goods_id']][$sku['id']] = $sku;
        }

        return $data;
    }

    public static function getSkusByGoodsIds($goodsIds)
    {
        $skus = self::select([
            'id',
            'goods_id',
            'shop_id',
            'sku_attr_t1',
            'sku_attr_t2',
            'extinfo',
            'price',
            'volume',
            'forecast_ship_time',
            'weight'
        ], [
            'goods_id' => $goodsIds,
            'status' => self::STATUS_PASSED
        ]);
        $formatData = [];
        foreach ($skus as $sku) {
            $formatData[$sku['goods_id']][$sku['id']] = $sku;
        }
        return $formatData;
    }


    public static function getSkuInfo($goodsIds, $isFormat = true, $isAll = true)
    {
        $data = [];

        $skuList = self::getSkuList($goodsIds, $isAll);

        if ($skuList) {
            foreach ($skuList as $goodsId => $skuInfoList) {
                $data[$goodsId] = $isFormat ? self::formatSkuInfoList($skuInfoList) : $skuInfoList;
            }
        }

        return $data;

    }

    protected static function formatSkuInfoList($skuInfoList)
    {
        $data = [
            'list' => [],
            'info' => [],
            'size' => []
        ];

        if (empty($skuInfoList)) {
            return $data;
        }

        foreach ($skuInfoList as $skuInfo) {

            array_push($data['list'], [
                'sku_id' => $skuInfo['id'],
                'name' => implode(' ', array_column($skuInfo['attr'], 'value')),
                'price' => $skuInfo['price'],
                'stock' => $skuInfo['stock'],
                'weight' => $skuInfo['weight'],
                'sku_no' => $skuInfo['sku_no'],
                'forecast_ship_time' => $skuInfo['forecast_ship_time'] == "0000-00-00" ? "" : $skuInfo['forecast_ship_time'],
                'volume' => $skuInfo['volume'],
            ]);

            foreach ($skuInfo['attr'] as $key => $attr) {

                if (!isset($data['info'][$key])) {
                    $data['info'][$key] = [
                        'tag' => $key,
                        'name' => $attr['title'],
                        'vals' => [],
                    ];
                }

                if (isset($data['info'][$key]['vals'])) {
                    $data['info'][$key]['vals'][$attr['id']] = [
                        'attr_id' => $attr['id'],
                        'name' => $attr['value'],
                        'extend_info' => $attr['extend_info'],
                        'extend_info_url' => $attr['extend_info_url'],
                        'extend_info_thumb_url' => $attr['extend_info_thumb_url'],
                    ];
                }
            }

            if (!empty($skuInfo['extinfo'])) {
                $extinfo = json_decode($skuInfo['extinfo'], 'true');
                if (is_array($extinfo)) {
                    array_push($data['size'], array_merge([
                        'sku_id' => $skuInfo['id'],
                        'name' => implode(' ', array_column($skuInfo['attr'], 'value')),
                    ], $extinfo));
                }
            }
        }

        if (!empty($data['info'])) {

            $data['info'] = array_values($data['info']);

            foreach ($data['info'] as &$value) {
                $value['vals'] = array_values($value['vals']);
            }

        }

        return $data;
    }

    public static function getSkuGoodsMap($skuIds)
    {
        $skus = self::select(["id", 'goods_id'], ['id' => $skuIds]);
        $formatData = [];
        foreach ($skus as $sku) {
            $formatData[$sku['id']] = $sku['goods_id'];
        }
        return $formatData;
    }


    public static function getInfo($skuId)
    {
        $info = self::get('*', ['id' => $skuId]);

        self::formatInfo($info);

        if (isset($info['goods_id'])) {
            $info['goods_info'] = GoodsBasicInfo::getInfo($info['goods_id']);
        }

        return $info;

    }


    public static function getInfoList($skuIds, $needFormat = true, $needGoodsInfo = true)
    {

        $infoList = self::select('*', ['id' => $skuIds]);

        if (empty($infoList)) {
            return [];
        }

        $infoList = array_column($infoList, null, 'id');


        if ($needFormat) {
            //格式化Attr信息
            $skuAttrIds = array_merge(array_column($infoList, 'sku_attr_t1'), array_column($infoList, 'sku_attr_t2'));

            $skuAttrIds = array_filter($skuAttrIds, function ($v) {
                return $v != 0;
            });

            $skuAttrInfoList = mGoodsSkuAttr::getInfoList($skuAttrIds);


            //格式化GoodsInfo信息
            $goodsIds = array_column($infoList, 'goods_id');
            $goodsInfoList = [];
            $goodsExtendInfoList = [];
            if ($needGoodsInfo) {
                $goodsInfoList = mGoodsBasicInfo::getInfoList($goodsIds, '*');
                $goodsExtendInfoList = mGoodsExtendInfo::getInfoList($goodsIds);
            }


            $infoList = array_map(function ($info) use ($skuAttrInfoList, $goodsInfoList, $goodsExtendInfoList, $needGoodsInfo) {
                foreach ($info as $key => &$value) {
                    switch ($key) {
                        case 'sku_attr_t1':
                            $info['sku_attr_t1_desc'] = $info['sku_attr_t1'] > 0 ? $skuAttrInfoList[$info['sku_attr_t1']]['value'] : '';
                            break;
                        case 'sku_attr_t2':
                            $info['sku_attr_t2_desc'] = $info['sku_attr_t2'] > 0 ? $skuAttrInfoList[$info['sku_attr_t2']]['value'] : '';
                            break;
                    }
                }

                if (isset($info['sku_attr_t1_desc']) && isset($info['sku_attr_t2_desc'])) {
                    $info['sku_attr_desc'] = [$info['sku_attr_t1_desc'], $info['sku_attr_t2_desc']];
                }

                if (isset($info['goods_id']) && $needGoodsInfo) {
                    $info['goods_info'] = $goodsInfoList[$info['goods_id']];
                    $info['goods_extend_info'] = $goodsExtendInfoList[$info['goods_id']];
                }

                return $info;
            }, $infoList);
        }


        return $infoList;
    }

    public static function formatInfo(&$info)
    {
        if (empty($info)) {
            return;
        }

        $skuAttrIds = [$info['sku_attr_t1'], $info['sku_attr_t2']];

        $skuAttrIds = array_filter($skuAttrIds, function ($v) {
            return $v != 0;
        });

        $skuAttrs = mGoodsSkuAttr::getInfoList($skuAttrIds);


        foreach ($info as $key => &$value) {
            switch ($key) {
                case 'sku_attr_t1':
                    $info['sku_attr_t1_desc'] = $info['sku_attr_t1'] > 0 ? $skuAttrs[$info['sku_attr_t1']]['value'] : '';
                    break;
                case 'sku_attr_t2':
                    $info['sku_attr_t2_desc'] = $info['sku_attr_t2'] > 0 ? $skuAttrs[$info['sku_attr_t2']]['value'] : '';
                    break;
            }
        }
        if (isset($info['sku_attr_t1_desc']) && isset($info['sku_attr_t2_desc'])) {
            $info['sku_attr_desc'] = [$info['sku_attr_t1_desc'], $info['sku_attr_t2_desc']];
        }

    }


    public static function getSkus($where, $is_has_passed = true)
    {
        if ($is_has_passed && !isset($where['status'])) {
            $where['status'] = self::STATUS_PASSED;
        }

        $skuInfos = self::select("*", $where);

        $skuInfos = array_map(function ($skuInfo) {
            $skuInfo['spec_params'] = json_decode($skuInfo['extinfo'], true);
            return $skuInfo;
        }, $skuInfos);

        return $skuInfos;
    }


    public static function setMutiStocks($stockInfo)
    {
//        $query = 'UPDATE ' . self::_TABLE_NAME . ' SET  stock  = CASE id ';
//        foreach ($stockInfo as $sku_id => $stock) {
//            self::update([
//                'stock' => $stock
//            ], [
//                'id' => $sku_id
//            ]);
//            $query .= sprintf(" WHEN %d THEN %d ", $sku_id, $stock);
//        }
//        $query .= " END WHERE  id IN (" . implode(", ", array_keys($currStocks)) . ")";
//        return self::query($query);

        foreach ($stockInfo as $item) {
            self::update(['stock' => $item['stock']], [
                'id' => $item['sku_id'],
            ])->rowcount();
        }

    }

    public static function delNotInSkuIds($shopId, $goodsId, $skuIds)
    {

        if (self::update(['status' => self::STATUS_DELETE], [
            "AND" => [
                "shop_id" => $shopId,
                "goods_id" => $goodsId,
                'id[!]' => $skuIds,
            ]
        ])->rowcount()) {

            return $goodsId;
        }
    }

    public static function getSkuField($field = '*', $skuId)
    {
        return self::get($field, ['id' => $skuId]);
    }

    public static function getSkuByWhere($method, $fields, $where)
    {
        return self::$method($fields, $where);
    }

    public static function updateSkuByWhere($fields, $where)
    {
        return self::update($fields, $where)->rowCount();
    }


}